package icu.sunway.gushenBlogBackEnd.Service.Implement;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import icu.sunway.gushenBlogBackEnd.Entity.Data.CommentDO;
import icu.sunway.gushenBlogBackEnd.Entity.Data.UserDO;
import icu.sunway.gushenBlogBackEnd.Entity.View.ResultVO;
import icu.sunway.gushenBlogBackEnd.Mapper.CommentMapper;
import icu.sunway.gushenBlogBackEnd.Message.CommentMessage;
import icu.sunway.gushenBlogBackEnd.Message.CommonMessage;
import icu.sunway.gushenBlogBackEnd.Service.CommentService;
import icu.sunway.gushenBlogBackEnd.Service.UserService;
import icu.sunway.gushenBlogBackEnd.utils.DateUtils;
import icu.sunway.gushenBlogBackEnd.utils.JwtUtil;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, CommentDO> implements CommentService {

    private final UserService userService;

    CommentServiceImpl(UserService userService) {
        this.userService = userService;
    }

    @Override
    public ResultVO<List<CommentDO>> getCommentListFromArticle(String article_id) {
        List<CommentDO> commentDOList;
        try {
            QueryWrapper<CommentDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("article_id", article_id);
            queryWrapper.orderByAsc("publish_time");
            commentDOList = list(queryWrapper);
            if (commentDOList == null) {
                throw new Exception();
            }
        } catch (Exception e) {
            return new ResultVO<>(400, CommentMessage.get_comment_list_from_article_fail, null);
        }
        return new ResultVO<>(200, CommentMessage.get_comment_list_from_article_success, commentDOList);
    }

    @Override
    public ResultVO<Long> getCommentCountFromArticle(String article_id) {
        long commentCount;
        try {
            QueryWrapper<CommentDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("article_id", article_id);
            commentCount = count(queryWrapper);
        } catch (Exception e) {
            return new ResultVO<>(400, CommentMessage.get_comment_count_from_article_fail, null);
        }
        return new ResultVO<>(200, CommentMessage.get_comment_count_from_article_success, commentCount);
    }

    @Override
    public ResultVO<Boolean> addCommentRoot(String article_id, String content, String token) {
        try {
            UserDO userDO = userService.getById(JwtUtil.parseTokenAsId(token));
            CommentDO commentDO = new CommentDO(
                    null,
                    userDO.getId(),
                    article_id,
                    content,
                    "root",
                    DateUtils.getCurDateString(),
                    userDO.getAvatar(),
                    userDO.getNickname(),
                    "root",
                    "root"
            );
            if (!save(commentDO)) {
                throw new Exception();
            }
        } catch (Exception e) {
            return new ResultVO<>(400, CommentMessage.add_comment_root_fail, false);
        }
        return new ResultVO<>(200, CommentMessage.add_comment_root_success, true);
    }

    @Override
    public ResultVO<Boolean> addCommentChild(String article_id, String to_comment_id, String parent_comment_id, String content, String token) {
        try {
            UserDO userDO = userService.getById(JwtUtil.parseTokenAsId(token));
            CommentDO toCommentDO = getById(to_comment_id);
            CommentDO commentDO = new CommentDO(
                    null,
                    userDO.getId(),
                    article_id,
                    content,
                    parent_comment_id,
                    DateUtils.getCurDateString(),
                    userDO.getAvatar(),
                    userDO.getNickname(),
                    to_comment_id,
                    toCommentDO.getUser_nickname()
            );
            if (!save(commentDO)) {
                throw new Exception();
            }
        } catch (Exception e) {
            return new ResultVO<>(400, CommentMessage.add_comment_child_fail + e.getMessage(), false);
        }
        return new ResultVO<>(200, CommentMessage.add_comment_child_success, true);
    }

    @Override
    public ResultVO<Boolean> removeComment(String id, String token) {
        try {
            CommentDO commentDO = getById(id);
            if (commentDO == null) {
                throw new Exception(CommonMessage.remove_object_not_exist);
            }
            if (token == null) {
                throw new Exception(CommonMessage.need_login_first);
            }
            try {
                JwtUtil.parseTokenAsId(token);
            } catch (Exception e) {
                throw new Exception(CommonMessage.login_status_invalid);
            }
            if (!Objects.equals(commentDO.getUser_id(), JwtUtil.parseTokenAsId(token))) {
                throw new Exception(CommonMessage.do_not_have_permission);
            }
            if (Objects.equals(commentDO.getParent_comment_id(), "root")) {
                QueryWrapper<CommentDO> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("parent_comment_id", commentDO.getId());
                remove(queryWrapper);
            }
            removeById(id);
        } catch (Exception e) {
            return new ResultVO<>(400, e.getMessage(), false);
        }
        return new ResultVO<>(200, CommentMessage.remove_comment_success, true);
    }
}
